package com.kexilo.core.security.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kexilo.core.security.domain.RefreshToken;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 刷新令牌映射层
 *
 * @author Kexilo
 */
@Mapper
public interface RefreshTokenMapper extends BaseMapper<RefreshToken> {

    /**
     * 根据刷新令牌查询
     *
     * @param refreshToken 刷新令牌
     * @return RefreshToken
     */
    RefreshToken selectByRefreshToken(@Param("refreshToken") String refreshToken);

    /**
     * 根据访问令牌查询
     *
     * @param accessToken 访问令牌
     * @return RefreshToken
     */
    RefreshToken selectByAccessToken(@Param("accessToken") String accessToken);

    /**
     * 根据用户ID查询有效的刷新令牌
     *
     * @param userId 用户ID
     * @return List<RefreshToken>
     */
    List<RefreshToken> selectValidByUserId(@Param("userId") Long userId);

    /**
     * 根据用户ID和设备ID查询
     *
     * @param userId 用户ID
     * @param deviceId 设备ID
     * @return RefreshToken
     */
    RefreshToken selectByUserIdAndDeviceId(@Param("userId") Long userId, @Param("deviceId") String deviceId);

    /**
     * 撤销用户所有刷新令牌
     *
     * @param userId 用户ID
     * @return 影响行数
     */
    int revokeAllByUserId(@Param("userId") Long userId);

    /**
     * 撤销指定刷新令牌
     *
     * @param refreshToken 刷新令牌
     * @return 影响行数
     */
    int revokeByRefreshToken(@Param("refreshToken") String refreshToken);

    /**
     * 标记令牌为已使用
     *
     * @param refreshToken 刷新令牌
     * @return 影响行数
     */
    int markAsUsed(@Param("refreshToken") String refreshToken);

    /**
     * 更新最后使用时间和使用次数
     *
     * @param refreshToken 刷新令牌
     * @param lastUsedTime 最后使用时间
     * @return 影响行数
     */
    int updateLastUsedTime(@Param("refreshToken") String refreshToken, @Param("lastUsedTime") LocalDateTime lastUsedTime);

    /**
     * 清理过期的刷新令牌
     *
     * @return 清理数量
     */
    int deleteExpiredTokens();

    /**
     * 清理已使用的刷新令牌（保留N天）
     *
     * @param beforeTime 保留时间点
     * @return 清理数量
     */
    int deleteUsedTokensBefore(@Param("beforeTime") LocalDateTime beforeTime);
}
